import {
  _decorator,
  Component,
  Node,
  Sprite,
  SpriteFrame,
} from "cc";
import { CellType, Exits } from "./Types";
const { ccclass, property } = _decorator;

@ccclass("Cell")
export class Cell extends Component {
  private type: CellType;
  private exits: boolean[] = [false, false, false, false];

  private sprite: Sprite = null;

  private exitNodes: { [key: number]: Node } = {};

  @property(SpriteFrame)
  private treeSprite: SpriteFrame = null;

  @property(SpriteFrame)
  private characterSprite: SpriteFrame = null;

  @property(SpriteFrame)
  private homeSprite: SpriteFrame = null;

  @property(SpriteFrame)
  private roadLeftDownSprite: SpriteFrame = null;

  @property(SpriteFrame)
  private roadUpDownSprite: SpriteFrame = null;

  @property(SpriteFrame)
  private roadRightDownSprite: SpriteFrame = null;

  @property(SpriteFrame)
  private roadUpRightSprite: SpriteFrame = null;

  @property(SpriteFrame)
  private roadLeftRightSprite: SpriteFrame = null;

  @property(SpriteFrame)
  private roadUpLeftSprite: SpriteFrame = null;

  @property(SpriteFrame)
  private emptySprite: SpriteFrame = null;

  start() {}

  setPosition(x: number, y: number) {
    this.node.setPosition(x * 128, y * 128);
  }

  update(deltaTime: number) {}

  hasExit(direction): boolean {
    if (direction === "up") {
      return this.exits[0];
    } else if (direction === "right") {
      return this.exits[1];
    } else if (direction === "down") {
      return this.exits[2];
    } else if (direction === "left") {
      return this.exits[3];
    }
    return false;
  }

  getType(): CellType {
    return this.type;
  }

  setType(type: CellType) {
    this.type = type;
    if (!this.sprite) {
      this.sprite = this.getComponent(Sprite);
      if (!this.sprite) {
        this.sprite = this.addComponent(Sprite);
      }
    }

    switch (type) {
      case CellType.Tree:
        this.sprite.spriteFrame = this.treeSprite;
        break;
      case CellType.Character:
        this.sprite.spriteFrame = this.characterSprite;
        break;
      case CellType.Home:
        this.sprite.spriteFrame = this.homeSprite;
        break;
      case CellType.Road:
        const exits = this.getExits();

        // Check each road type condition
        const conditions = {
          leftDown:
            exits[0] === false &&
            exits[1] === false &&
            exits[2] === true &&
            exits[3] === true,
          upDown:
            exits[0] === true &&
            exits[1] === false &&
            exits[2] === true &&
            exits[3] === false,
          rightDown:
            exits[0] === false &&
            exits[1] === true &&
            exits[2] === true &&
            exits[3] === false,
          upRight:
            exits[0] === true &&
            exits[1] === true &&
            exits[2] === false &&
            exits[3] === false,
          leftRight:
            exits[0] === false &&
            exits[1] === true &&
            exits[2] === false &&
            exits[3] === true,
          upLeft:
            exits[0] === true &&
            exits[1] === false &&
            exits[2] === false &&
            exits[3] === true,
        };

        // leftDown
        if (conditions.leftDown) {
          this.sprite.spriteFrame = this.roadLeftDownSprite;
        }
        // upDown
        else if (conditions.upDown) {
          this.sprite.spriteFrame = this.roadUpDownSprite;
        }
        // rightDown
        else if (conditions.rightDown) {
          this.sprite.spriteFrame = this.roadRightDownSprite;
        }
        // upRight
        else if (conditions.upRight) {
          this.sprite.spriteFrame = this.roadUpRightSprite;
        }
        // leftRight
        else if (conditions.leftRight) {
          this.sprite.spriteFrame = this.roadLeftRightSprite;
        }
        // upLeft
        else if (conditions.upLeft) {
          this.sprite.spriteFrame = this.roadUpLeftSprite;
        } else {
          this.sprite.spriteFrame = this.emptySprite;
        }
        break;
      case CellType.Empty:
        this.sprite.spriteFrame = this.emptySprite;
        break;
    }
  }

  onLoad() {
    this.sprite = this.getComponent(Sprite);
    if (!this.sprite) {
      this.sprite = this.addComponent(Sprite);
    }
  }

  getExits(): boolean[] {
    return [...this.exits];
  }

  setExits(exits: boolean[]) {
    this.exits = [...exits];
  }

  getExitsObject(): Exits {
    return {
      up: this.exits[0],
      right: this.exits[1],
      down: this.exits[2],
      left: this.exits[3],
    };
  }

  setExitsFromObject(exits: Exits) {
    this.exits = [exits.up, exits.right, exits.down, exits.left];
  }
}
